﻿
using BackupLib.Remoting;

namespace BackupSvc
{
    using System;
    using System.Diagnostics;
    using System.Security.Principal;
    using System.ServiceProcess;
    using System.Runtime.Remoting;
    using System.Runtime.Remoting.Channels;
    using System.Runtime.Remoting.Channels.Ipc;
    using System.Threading;
    using BackupLib;
    using System.Collections;

    public partial class BackupSvc : ServiceBase
    {
        private const int SleepIntervall = 2000;
        private Thread WorkerThread;

        public BackupSvc()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            StartSvc();
        }

        protected override void OnStop()
        {
            StopSvc();
        }

        internal void StopSvc()
        {
            // New in .NET Framework version 2.0.
            RequestAdditionalTime(4000);
            // Signal the worker thread to exit.
            if ((WorkerThread != null) && (WorkerThread.IsAlive))
            {
                EventLog.WriteEntry("BackupSvc", "Stopping");
                WorkerThread.Abort();

            }

            // Indicate a successful exit.
            ExitCode = 0;
        }

        internal void StartSvc()
        {
            ServiceSettings.BackupProject = XML.Deserialize();
            ServiceSettings.NextExecution = ServiceSettings.BackupProject.GetNextExecution();
                        
            // Start a separate thread that does the actual work.

            if ((WorkerThread == null) ||
                ((WorkerThread.ThreadState &
                 (System.Threading.ThreadState.Unstarted | System.Threading.ThreadState.Stopped)) != 0))
            {
                EventLog.WriteEntry("BackupSvc", "Starting");

                WorkerThread = new Thread(Worker);
                WorkerThread.Start();
            }

            IPCHelper.RegisterServer();
        }

        public void Worker()
        {
            EventLog.WriteEntry("BackupSvc", "Started");

            try
            {
                do
                {
                    if (ServiceSettings.NextExecution<DateTime.Now)
                    {
                        EventLog.WriteEntry("BackupSvc", "Run Backup");
                        ServiceSettings.BackupProject.OnFile += ServiceSettings.BackupProject_OnFile;
                        ServiceSettings.BackupProject.OnStart += ServiceSettings.BackupProject_OnStart;
                        ServiceSettings.BackupProject.OnStop += ServiceSettings.BackupProject_OnStop;
                        ServiceSettings.BackupProject.DoBackup();
                        ServiceSettings.NextExecution = ServiceSettings.BackupProject.GetNextExecution();
                        EventLog.WriteEntry("BackupSvc", "Finished Backup. Next Execution: " + ServiceSettings.NextExecution);
                    }

                    Thread.Sleep(SleepIntervall);
                }
                while (true);
            }
            catch (ThreadAbortException)
            {}

            EventLog.WriteEntry("BackupSvc", "Exiting");
        }
    }
}
